package com.zx.flow.api.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

@Slf4j
public class JWTUtil {

    public static final String JWT_KEY = "Authorization";

    public static final String SECRETID_KEY = "secretId";

    private static String PAYLOAD_KEY = "info";

    /**
     * 生成token，自定义过期时间 毫秒
     *
     * @return
     */
    public static String generateToken(String secretId, String secretKey, Object obj) {
        if (StringUtils.isEmpty(secretKey) || StringUtils.isEmpty(secretId)) {
            return null;
        }
        try {
            // 指定token过期时间为1分钟
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.MINUTE, 60);
            // 私钥和加密算法
            Algorithm algorithm = Algorithm.HMAC256(secretKey);
            // 设置头部信息
            Map<String, Object> header = new HashMap<>(2);
            header.put("Type", "Jwt");
            header.put("alg", "HS256");
            return JWT.create()
                    // 1.header
                    .withHeader(header)
                    // 2.Payload
                    .withClaim(PAYLOAD_KEY, Util.getJsonStr(obj))
                    // 3.过期时间
                    .withExpiresAt(calendar.getTime())
                    // signature
                    .sign(algorithm);
        } catch (Exception e) {
            log.error("生成token失败, error is:{}", e);
            throw e;
        }
    }

    /**
     * 检验token获得其中存储的信息
     *
     * @param jwt
     * @return
     */
    public static <T> T verifyAndGet(String secretId, String secretKey, String jwt, Class<T> clazz) {
        if (StringUtils.isEmpty(secretKey) || StringUtils.isEmpty(secretId)) {
            return null;
        }
        // 创建解析对象，使用的算法和secret要与创建token时保持一致
        Algorithm algorithm = Algorithm.HMAC256(secretKey);
        JWTVerifier verifier = JWT.require(algorithm).build();
        // 解析指定的token
        DecodedJWT decodedJWT = verifier.verify(jwt);
        // 获取解析后的token中的payload信息
        String tokenInfo = decodedJWT.getClaim(PAYLOAD_KEY).asString();
        return Util.getJavaObject(tokenInfo, clazz);
    }


}
